﻿using System.Data.OleDb;
using System.Data;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Xml.XPath;
using System.Xml.Xsl;
using System.Xml;
using System;

namespace Yonyou.U8.QuickImport
{
    public class ExcelToXml : IDataImport
    {
        private Context _Context;

        private bool IsEmpty;

        public bool ArchIsEmpty
        {
            get
            {
                return IsEmpty;
            }
        }

        public event InitialRows InitSetup;

        public event SetValue ValueSet;

        public ExcelToXml(Context context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            _Context = context;
            IsEmpty = false;
        }

        public string[] transform(string type, string filename, string proctype)
        {
            DataSet dataSet = FillDataset(filename, type);
            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.LoadXml(dataSet.GetXml());
            XmlTextWriter xmlTextWriter = new XmlTextWriter(Context.QIPath + "\\dataset_data.xml", null);
            xmlTextWriter.Formatting = Formatting.Indented;
            xmlDocument.Save(xmlTextWriter);
            xmlTextWriter.Close();
            XslTransform xslTransform = new XslTransform();
            string url = CommonUtil.LoadStyleSheet(type, _Context.Login);
            try
            {
                xslTransform.Load(url);
            }
            catch (XsltCompileException ex)
            {
                MessageBox.Show(ex.Message);
                return null;
            }
            catch (XmlException ex2)
            {
                MessageBox.Show(ex2.Message);
                return null;
            }
            try
            {
                XsltArgumentList xsltArgumentList = new XsltArgumentList();
                xsltArgumentList.AddParam("proctype", "", proctype);
                DataTable dataTable = dataSet.Tables[0];
                for (int i = 0; i < dataSet.Tables.Count; i++)
                {
                    DeleteEmptyRow(dataSet.Tables[i]);
                }
                if (dataTable.Rows.Count <= 0 && proctype != "4")
                {
                    IsEmpty = true;
                    return null;
                }
                this.InitSetup(dataTable.Rows.Count, Path.GetFileNameWithoutExtension(filename));
                this.ValueSet(dataTable.Rows.Count / 2);
                string xml = dataSet.GetXml();
                xml = TrimXmlField(xml);
                StringReader textReader = new StringReader(xml);
                XPathDocument input = new XPathDocument(textReader);
                MemoryStream memoryStream = new MemoryStream();
                XmlTextWriter xmlTextWriter2 = new XmlTextWriter(memoryStream, null);
                xmlTextWriter2.WriteProcessingInstruction("xml", "version='1.0' encoding='utf-8'");
                xslTransform.Transform(input, xsltArgumentList, xmlTextWriter2, null);
                string[] array = new string[1];
                string text = Encoding.UTF8.GetString(memoryStream.GetBuffer());
                if (proctype == "5")
                {
                    text = XmlAdmin.ClearEmptyNode(text);
                }
                array[0] = text;
                this.ValueSet(dataTable.Rows.Count);
                return array;
            }
            catch (XmlException ex3)
            {
                MessageBox.Show("excel向dataset转换出错：" + ex3.Message);
                return null;
            }
        }

        private DataSet FillDataset(string filename, string type)
        {
            if (!File.Exists(filename))
            {
                throw new Exception(string.Format("Excel文件 {0} 不存在.", filename));
            }
            string connectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + filename + "; Extended Properties=Excel 8.0;";
            OleDbConnection oleDbConnection = new OleDbConnection(connectionString);
            oleDbConnection.Open();
            OleDbCommand selectCommand = new OleDbCommand("SELECT * FROM [Sheet1$]", oleDbConnection);
            OleDbDataAdapter oleDbDataAdapter = new OleDbDataAdapter();
            oleDbDataAdapter.SelectCommand = selectCommand;
            DataSet dataSet = new DataSet();
            dataSet.DataSetName = "ufinterface";
            oleDbDataAdapter.Fill(dataSet, type);
            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.Load(Path.Combine(Context.U8Path, "ExcelModel\\ChildArch.xml"));
            XmlNode xmlNode = xmlDocument.SelectSingleNode("//arch[@type='" + type + "']");
            if (xmlNode != null)
            {
                XmlNodeList childNodes = xmlNode.ChildNodes;
                foreach (XmlNode item in childNodes)
                {
                    string innerText = item.Attributes.GetNamedItem("type").InnerText;
                    string innerText2 = item.Attributes.GetNamedItem("name").InnerText;
                    string cmdText = "select * from [" + innerText2 + "$]";
                    selectCommand = (oleDbDataAdapter.SelectCommand = new OleDbCommand(cmdText, oleDbConnection));
                    oleDbDataAdapter.Fill(dataSet, innerText);
                }
            }
            DateTimeToString(dataSet);
            oleDbConnection.Close();
            return dataSet;
        }

        private void DateTimeToString(DataSet dataset)
        {
            foreach (DataTable table in dataset.Tables)
            {
                for (int i = 0; i < table.Columns.Count; i++)
                {
                    DataColumn dataColumn = table.Columns[i];
                    if (dataColumn.DataType != Type.GetType("System.DateTime"))
                    {
                        continue;
                    }
                    DataColumn dataColumn2 = table.Columns.Add(dataColumn.Caption + "new", Type.GetType("System.String"));
                    for (int j = 0; j < table.Rows.Count; j++)
                    {
                        if (table.Rows[j][dataColumn] != DBNull.Value)
                        {
                            string value = ((DateTime)table.Rows[j][dataColumn]).ToString("yyyy-MM-dd");
                            table.Rows[j][dataColumn2] = value;
                        }
                        else
                        {
                            table.Rows[j][dataColumn2] = DBNull.Value;
                        }
                    }
                    string caption = dataColumn.Caption;
                    string columnName = dataColumn.ColumnName;
                    dataColumn.Caption = caption + "old";
                    dataColumn.ColumnName = columnName + "old";
                    dataColumn2.Caption = caption;
                    dataColumn2.ColumnName = columnName;
                }
            }
        }

        private void BadStringReplace(DataSet dataset)
        {
            for (int i = 0; i < dataset.Tables.Count; i++)
            {
                DataTable dataTable = dataset.Tables[i];
                for (int j = 0; j < dataTable.Rows.Count; j++)
                {
                    for (int k = 0; k < dataTable.Columns.Count; k++)
                    {
                        if (dataTable.Columns[k].DataType == Type.GetType("System.String"))
                        {
                            dataTable.Rows[j][k] = dataTable.Rows[j][k].ToString().Replace("&", "&amp;");
                        }
                    }
                }
            }
        }

        private void DeleteEmptyRow(DataTable table)
        {
            int num = table.Rows.Count - 1;
            while (num >= 0)
            {
                bool flag = false;
                for (int i = 0; i < table.Columns.Count; i++)
                {
                    if (table.Rows[num][i].ToString().Trim() != "")
                    {
                        flag = true;
                        break;
                    }
                }
                if (!flag)
                {
                    table.Rows.RemoveAt(num);
                    num--;
                    continue;
                }
                break;
            }
        }

        private string TrimXmlField(string strxml)
        {
            XmlDocument xmlDocument = new XmlDocument();
            XmlDocument xmlDocument2 = new XmlDocument();
            try
            {
                xmlDocument.LoadXml(strxml);
                xmlDocument2.LoadXml(strxml);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return strxml;
            }
            xmlDocument2.SelectSingleNode("/ufinterface").RemoveAll();
            XmlNodeList childNodes = xmlDocument.SelectSingleNode("/ufinterface").ChildNodes;
            foreach (XmlNode item in childNodes)
            {
                XmlNodeList childNodes2 = item.ChildNodes;
                XmlNode xmlNode2 = xmlDocument2.CreateNode(item.NodeType, item.Name, item.NamespaceURI);
                foreach (XmlNode item2 in childNodes2)
                {
                    string name = item2.Name.Replace("_x0020_", "");
                    XmlNode xmlNode4 = xmlDocument2.CreateNode(item2.NodeType, name, item2.NamespaceURI);
                    xmlNode4.InnerText = item2.InnerText;
                    xmlNode2.AppendChild(xmlNode4);
                }
                xmlDocument2.SelectSingleNode("/ufinterface").AppendChild(xmlNode2);
            }
            return xmlDocument2.InnerXml;
        }

        public void logWrite(string logpath, string[,] strLog, string[] rxmlstr, string id, string procType)
        {
            WriteExcel writeExcel = new WriteExcel();
            writeExcel.Write(logpath, Path.GetFileName(logpath), strLog, strLog.Length, rxmlstr, id, procType);
            GC.Collect();
        }
    }
}